/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.npmpackage.core.npminstall;

import com.inspur.edp.web.common.entity.NodeJsCommandEnum;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.io.NodejsFunctionUtility;
import com.inspur.edp.web.common.utility.*;
import com.inspur.edp.web.npmpackage.api.entity.NpmInstallParameter;
import com.inspur.edp.web.npmpackage.api.entity.NpmPackageResponse;
import org.apache.commons.lang3.SystemUtils;

/**
 * npm install 命令执行
 *
 * @author noah
 */
class NpmInstallCommandExecutor {
    /**
     * 命令执行
     *
     * @param npmInstallParameter
     * @param currentServerPath
     */
    public static NpmPackageResponse execute(NpmInstallParameter npmInstallParameter, String currentServerPath, String parentNodeModulesPath) {
        // 构造install 命令参数 执行npm包安装操作
        String npmCommandExecuteWithPath = NodejsFunctionUtility.getNodeJsCommandInServerWithOS(NodeJsCommandEnum.Npm, currentServerPath);


        String npmInstallCommand = NpmInstallCommandParameterGenerator.generate(npmInstallParameter);


        String[] command = new String[1];
        if (SystemUtils.IS_OS_WINDOWS) {
            command = new String[4];
            // 盘符独立打开
            command[0] = FileUtility.getAbsolutePathHead(parentNodeModulesPath);
            command[1] = "cd " + parentNodeModulesPath;
            command[2] = npmCommandExecuteWithPath + " update " + npmInstallCommand;
            command[3] = "exit";
        } else if (SystemUtils.IS_OS_LINUX || SystemUtils.IS_OS_MAC_OSX) {
            command = new String[3];
            command[0] = "cd " + parentNodeModulesPath;
            command[1] = npmCommandExecuteWithPath + " update " + npmInstallCommand;
            command[2] = "exit";
        }
        // 执行npm 包安装
        return runCommand(command, true);
    }

    private static NpmPackageResponse runCommand(String[] commands, boolean isWait) {
        String command = String.join(" && ", commands);
        return runCommand(command, isWait);
    }

    /**
     * 执行命令
     *
     * @param command 待执行命令
     * @param isWait  是否等待返回结果
     */
    private static NpmPackageResponse runCommand(String command, boolean isWait) {
        StringBuffer errorSB = new StringBuffer();
        String errorMessage = CommandLineUtility.executeCommand(command, errorSB);
        // 如果出现编译错误 那么通过异常的方式将错误信息进行抛出
        if (!StringUtility.isNullOrEmpty(errorMessage)) {
            return NpmPackageResponse.createError("npm install failed, the reason is " + errorMessage);
        }

        // 如果存在输出异常 那么不再继续执行
        if (!StringUtility.isNullOrEmpty(errorSB.toString()) && errorSB.toString().toLowerCase().contains("npm err")) {
            return NpmPackageResponse.createError(errorSB.toString());
        }

        return NpmPackageResponse.create();
    }


}
